package com.biubiu.biubiuexam.services;

import com.biubiu.biubiuexam.common.dto.StudentClazzDto;
import com.biubiu.biubiuexam.common.dto.StudentExamInfoDto;
import com.biubiu.biubiuexam.common.dto.StudentExamQuestionDto;
import com.biubiu.biubiuexam.common.lang.Result;
import com.biubiu.biubiuexam.nosql.model.Exam;
import com.biubiu.biubiuexam.nosql.model.ExamPaper;
import com.biubiu.biubiuexam.nosql.model.ExamQuestion;
import com.biubiu.biubiuexam.nosql.repository.ExamPaperRepository;
import com.biubiu.biubiuexam.nosql.repository.ExamQuestionRepository;
import com.biubiu.biubiuexam.nosql.repository.ExamRepository;
import com.biubiu.biubiuexam.sql.entity.Clazz;
import com.biubiu.biubiuexam.sql.entity.User;
import com.biubiu.biubiuexam.sql.repository.ClazzRepository;
import com.biubiu.biubiuexam.sql.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * The type Student service.
 */
@Service
public class StudentService {

    private final UserRepository userRepository;

    private final ClazzRepository clazzRepository;

    private final ExamRepository examRepository;

    private final ExamPaperRepository examPaperRepository;

    private final ExamQuestionRepository examQuestionRepository;

    /**
     * Instantiates a new Student service.
     *
     * @param userRepository         the user repository
     * @param clazzRepository        the clazz repository
     * @param examRepository         the exam repository
     * @param examPaperRepository    the exam paper repository
     * @param examQuestionRepository the exam question repository
     */
    @Autowired
    public StudentService(UserRepository userRepository,
                          ClazzRepository clazzRepository,
                          ExamRepository examRepository,
                          ExamPaperRepository examPaperRepository,
                          ExamQuestionRepository examQuestionRepository) {
        this.userRepository = userRepository;
        this.clazzRepository = clazzRepository;
        this.examRepository = examRepository;
        this.examPaperRepository = examPaperRepository;
        this.examQuestionRepository = examQuestionRepository;
    }

    /**
     * Gets all clazz of student.
     *
     * @param studentId the student id
     * @return the all clazz of student
     */
    public Result getAllClazzOfStudent(Long studentId) {
        User user = userRepository.getById(studentId);

        List<Clazz> list = user.getClazz();
        List<StudentClazzDto> reList = new ArrayList<>();

        for (Clazz clazz : list) {
            StudentClazzDto studentClazzDto = new StudentClazzDto();
            studentClazzDto.setName(clazz.getName());
            studentClazzDto.setDescription(clazz.getDescription());
            studentClazzDto.setCode(clazz.getCode());
            studentClazzDto.setTeacherName(clazz.getTeacher().getNickName());
            studentClazzDto.setTeacherEmail(clazz.getTeacher().getEmail());
            reList.add(studentClazzDto);
        }

        return Result.success(reList);
    }

    /**
     * Join clazz result.
     *
     * @param studentId the student id
     * @param code      the code
     * @return the result
     */
    public Result joinClazz(Long studentId, String code) {
        User student = userRepository.getById(studentId);
        for (Clazz item : student.getClazz()) {
            if (item.getCode().equals(code)) {
                return Result.fail(403, "您已经在班级中！", null);
            }
        }

        Clazz clazz = clazzRepository.findByCode(code);
        if (clazz == null) {
            return Result.fail(404, "找不到相应的班级！", null);
        }
        clazz.getStudents().add(student);
        clazzRepository.save(clazz);

        StudentClazzDto studentClazzDto = new StudentClazzDto();
        studentClazzDto.setName(clazz.getName());
        studentClazzDto.setDescription(clazz.getDescription());
        studentClazzDto.setCode(clazz.getCode());
        studentClazzDto.setTeacherName(clazz.getTeacher().getNickName());
        studentClazzDto.setTeacherEmail(clazz.getTeacher().getEmail());

        return Result.success(studentClazzDto);
    }

    /**
     * Exit clazz result.
     *
     * @param studentId the student id
     * @param code      the code
     * @return the result
     */
    public Result exitClazz(Long studentId, String code) {
        Clazz clazz = clazzRepository.findByCode(code);
        if (clazz == null) {
            return Result.fail(404, "找不到相应的班级！", null);
        }

        int len = clazz.getStudents().size();
        clazz.getStudents().removeIf((temp) -> Objects.equals(temp.getId(), studentId));

        if (len == clazz.getStudents().size()) {
            return Result.fail(400, "您不在班级中！", null);
        }
        clazzRepository.save(clazz);
        return Result.success(null);
    }


    /**
     * Gets my all exams.
     *
     * @param studentId the student id
     * @return the my all exams
     */
    public Result getMyAllExams(Long studentId) {
        User student = userRepository.getById(studentId);
        List<Clazz> list = student.getClazz();
        List<Exam> examList = new ArrayList<>();
        for (Clazz clazz : list) {
            examList.addAll(examRepository.findAllExamByClazzId(clazz.getId()));
        }
        List<StudentExamInfoDto> reList = new ArrayList<>();

        for (Exam exam : examList) {
            StudentExamInfoDto temp = new StudentExamInfoDto();
            temp.setName(exam.getName());
            temp.setDescription(exam.getDescription());
            temp.setStartTime(exam.getStartTime());
            temp.setEndTime(exam.getEndTime());
            temp.setLink(exam.getLink());
            reList.add(temp);
        }

        return Result.success(reList);
    }

    /**
     * Gets exam all questions.
     *
     * @param studentId the student id
     * @param link      the link
     * @return the exam all questions
     */
    public Result getExamAllQuestions(Long studentId, String link) {
        Exam exam = examRepository.findExamByLink(link);
        if (exam == null) {
            return Result.fail(404, "没有对应的考试！", null);
        }
        String examPaperId = exam.getExamPaperLinks().get((int) (studentId % exam.getExamPaperLinks().size()));

        ExamPaper examPaper = examPaperRepository.findExamPaperById(examPaperId);

        if (examPaper == null) {
            return Result.fail(404, "没有对应的试卷！", null);
        }

        List<StudentExamQuestionDto> examList = new ArrayList<>();

        for (String questionLink : examPaper.getExamQuestionLinks()) {
            ExamQuestion examQuestion = examQuestionRepository.findExamQuestionByLink(questionLink);
            if (examQuestion != null) {
                StudentExamQuestionDto temp = new StudentExamQuestionDto();
                temp.setType(examQuestion.getType());
                // TODO: 避免输出题目答案，其他的正常输出
                //temp.setContent(examQuestion.getContent());
                temp.setLink(examQuestion.getLink());
                examList.add(temp);
            }
        }

        return Result.success(examList);
    }

}
